/* 会計 */
;
(function($, undefined) {
  "use strict";
  $.fn.account = function(option) {
    option = $.extend({
      dateMomentFormat : 'YYYY/MM/DD',
      dateMaskFormat : '2999/19/39',
      codeSearchUrl : '/search',
      selectors : {
        code : 'code',
        title : 'title',
        collapse : 'icon-chevron-down',
        expand : 'icon-chevron-up',
        moveup : 'icon-arrow-up',
        movedown : 'icon-arrow-down',
        add : 'icon-plus',
        del : 'icon-remove',
        merge : 'icon-resize-full',
        split : 'icon-resize-small',
        clear : 'icon-tag',
      },
      holder : '.frame'
    }, option);
    
    function refresh(e) {
       var sum = [];
       e.find('.entry').each(function() {
         $(this).find('.amount').each(function(i,o) {
           if (!sum[i]) {
             sum[i] = 0;
           }
           var v = $(this).val().replace(/,/g,'');
           sum[i] += Number(v);
         });
       });
       $.each(sum,function(i,o){
         e.find('.amount-' + (i+1)).text(o);
       });
    };
    function init(e) {
      // Collapse
      e.on({
        'click' : function($evt) {
          var $e = $(this).removeClass(option.selectors.collapse).addClass(option.selectors.expand);
          var $h = $e.closest(option.holder);
          if ($h.hasClass('foot')) {
            e.find('.'+option.selectors.collapse).click();
          } else {
            $h.find('textarea').hide();
          }
        }
      }, '.' + option.selectors.collapse);
      // Expand
      e.on({
        'click' : function($evt) {
          var $e = $(this).removeClass(option.selectors.expand).addClass(option.selectors.collapse);
          var $h = $e.closest(option.holder);
          if ($h.hasClass('foot')) {
            e.find('.'+option.selectors.expand).click();
          } else {
            $e.closest(option.holder).find('textarea').show();
          }
        }
      }, '.' + option.selectors.expand);
      // Move UP
      e.on({
        'click' : function($evt) {
          var $e = $(this).closest(option.holder);
          $e.prev().not('.head,.foot').before($e);
        }
      }, '.' + option.selectors.moveup);
      // Move DOWN
      e.on({
        'click' : function($evt) {
          var $e = $(this).closest(option.holder);
          $e.next().not('.head,.foot').after($e);
        }
      }, '.' + option.selectors.movedown);
      // Clear Data
      e.on({
        'click' : function($evt) {
          var $e = $(this).closest(option.holder);
          $e.find('input:visible,textarea').val('');
          $e.find('.title').html('');
        }
      }, '.' + option.selectors.clear);
      // Add Data
      e.on({
        'click' : function($evt) {
          var $e = $(this).closest(option.holder);
          $e.after(init($e.clone()).removeClass('active'));
        }
      }, '.' + option.selectors.add);
      // Delete Data
      e.on({
        'click' : function($evt) {
          if (e.find('.entry').size()>1) {
            var $e = $(this).closest(option.holder).remove();
          }
        }
      }, '.' + option.selectors.del);
      // active frame
      e.on({
        'focus' : function($evt) {
          $(this).closest(option.holder).addClass('active').siblings().removeClass('active');
        },
        'click' : function($evt) {
          $(this).closest(option.holder).addClass('active').siblings().removeClass('active');
        }
      }, 'input,textarea,i');
      // amount
      e.on({
        'change keyup' : function($evt) {
          refresh(e);
        },
        'click' : function($evt) {
        }
      }, '.amount');
      
      // date mask
      e.find(".date").setMask({
        mask : option.dateMaskFormat,
        onValidate : function() {
          return moment($(this).val(), option.dateMomentFormat).isValid();
        }
      });
      // amount mask
      e.find(".amount").setMask({
        mask : '999,999,999,999',
        type: 'reverse'
      });
      
      // code search
      e.find('.' + option.selectors.code).textcomplete([ {
        match : /(.+)/,
        search : function(term, callback, el) {
          codeSearch(el, term, callback)
        },
        replace : function(value, el) {
          return codeReplace(el, value)
        },
        template : function(value) {
          return codeTemplate(value);
        },
        index : 1,
        cache : false
      } ]);
      return e;
    };
    function codeSearch(e, t, callback) {
      var q = {};
      var $e = $(e);
      if ($e.hasClass('main')) {
        q.codeM = t;
      } else {
        var $p = $e.closest(option.holder).find('.' + option.selectors.code + ',.' + option.selectors.title);
        var i = $p.index($e);
        q.codeM = $p.eq(i - 1).val();
        q.codeS = t;
      }
      $.getJSON(option.codeSearchUrl, q).done(function(resp) {
        callback(resp);
      }).fail(function() {
        callback([]);
      });
    };
    function codeReplace(e, v) {
      var $e = $(e);
      $e.data('code', v);
      var $p = $e.closest(option.holder).find('.' + option.selectors.code + ',.' + option.selectors.title);
      var i = $p.index($e);
      $p.eq(i + 2).html(v.name);
      return v.code;
    };
    function codeTemplate(v) {
      return v.code + ' : ' + v.name;
    }
    this.each(function() {
      init($(this));
    });
    // ※外部から参照可能な関数
    $.fn.publicMethod = function(options) {
    //
    };
    return this;
  };
})(jQuery);
